home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-18 | 3.0 KB | 209 lines | [TEXT/R*ch] |
- // (c) copyright 1995,1996, Jon Kalb, Liberty Software
- // Kalb@LibertySoft.com
- // You may freely incorporate this code into any machine-
- // readable project. You may modify this code, but you may
- // not remove this statement.
-
- #include "doutstream"
-
- #include <string.h> // for strlen() and strcpy()
- #include <OSUtils.h> // for SysBeep();
-
- static debugbuf debugstream;
- ostream dout(&debugstream);
-
- unsigned int debugbufinit::count = 0;
-
- // this is debug code -- performance is not a goal
-
- void debugbuf::init() // called by friend class debugbufinit
- {
- pbeg[0] = '\0';
- pnext = pbeg + kSizeOfLengthByte;
- pend = pnext + kMaxDebugStrReadableString;
- alertCount = 0;
- }
-
-
- int debugbuf::overflow(int c)
- {
- if (EOF == c)
- {
- return '\0'; // returning EOF indicates an error
- }
- else
- {
- outputchar(c);
- return c;
- }
- }
-
-
- int debugbuf::xsputn(const char *s, int n)
- {
- for (int i = 0; i < n; ++i)
- {
- outputchar(s[i]);
- }
- return n; // we always process all of the chars
- }
-
-
- void debugbuf::outputchar(char c)
- {
- switch (c)
- {
- case '\b':
- backspace();
- break;
- case '\f':
- formfeed();
- break;
- case '\n':
- flushdebugstring();
- break;
- case '\r':
- softflush();
- break;
- case '\t':
- horztab();
- break;
- case '\v':
- verttab();
- break;
- case '\a':
- alert();
- break;
- case '\0':
- case '\x03':
- flushdebugstring(kStop);
- break;
- default:
- addchar(c);
- break;
- }
- }
-
-
- void debugbuf::backspace()
- {
- if (pbeg[0]) // if the buffer is empty, don't bother
- {
- --pnext;
- --pbeg[0];
- }
- // note that alerts cannot be backspaced away -- a
- // possible enhancement
- }
-
-
- void debugbuf::formfeed()
- {
- softflush();
- strcpy(pbeg, (char *)
- "\p_______________________________________________");
- pnext += strlen(pnext);
- flushdebugstring();
- }
-
-
- // both horizontal and verticle tabbing is done by brute
- // force -- performance is not a goal
- void debugbuf::horztab()
- {
- // we don't wrap tabs so if we are within kTabSize of
- // the end of the buffer then we just flush
- if (pend - pnext <= kTabSize)
- {
- flushdebugstring();
- }
- else
- {
- for (int i = 0; i < kTabSize; ++i)
- {
- addchar(' ');
- }
- }
- }
-
-
- void debugbuf::verttab()
- {
- int position = pnext - &pbeg[1];
- flushdebugstring();
- for (int i = 0; i < position; ++i)
- {
- addchar(' ');
- }
- }
-
-
- void debugbuf::alert()
- {
- ++alertCount;
- }
-
-
- void debugbuf::addchar(char c)
- {
- *pnext++ = c;
- ++pbeg[0];
- if (pnext == pend)
- {
- flushdebugstring();
- }
- }
-
-
- void debugbuf::softflush()
- {
- if ('\0' != pbeg[0])
- {
- flushdebugstring();
- }
- else
- {
- flushalerts();
- }
- }
-
- void debugbuf::flushalerts()
- {
- while (alertCount)
- {
- --alertCount;
- SysBeep(30);
- }
- }
-
- void debugbuf::flushdebugstring(int stop)
- {
- if (!stop)
- {
- addchar(';');
- addchar('g');
- }
- flushalerts();
- DebugStr((unsigned char *)pbeg);
- pbeg[0] = '\0';
- pnext = &pbeg[1];
- }
-
-
- debugbufinit::debugbufinit()
- {
- if (0 == count++)
- {
- debugstream.init();
- }
- }
-
- debugbufinit::~debugbufinit()
- {
- if (0 == --count)
- {
- // nothing to dispose, but we should flush
- debugstream.softflush();
- }
- }
-